﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LiveResults.Model
{
    public class Runner
    {
        public Runner()
        {
            RadioTimes = new Dictionary<int, int>();
        }

        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string ClassName { get; set; }
        public string ClubName { get; set; }
        public int StartTime { get; set; }
        public int Time { get; set; }
        public RunnerStatus Status { get; set; }
        public Dictionary<int, int> RadioTimes { get; set; }

        public OnlineLib.OnlineResult OnlineResult
        {
            get
            {
                OnlineLib.OnlineResult res = new OnlineLib.OnlineResult();
                res.DbID = ID;
                res.FirstName = FirstName;
                res.LastName = LastName;
                res.ClassName = ClassName;
                res.ClubName = ClubName;
                res.TotalTime = Time;
                res.Status = (int)Status;
                res.StartTime = StartTime;
                res.SplitControls = new List<int>();
                res.SplitTimes = new List<int>();
                if (RadioTimes != null)
                {
                    foreach (var kvp in RadioTimes)
                    {
                        res.SplitControls.Add(kvp.Key);
                        res.SplitTimes.Add(kvp.Value);
                    }
                }

                return res;
            }
        }

        public bool MergeNewValues(int startTime, int time, RunnerStatus status, Dictionary<int, int> radioTimes)
        {
            bool haveChanged = false;
            if (startTime != StartTime)
            {
                StartTime = startTime;
                haveChanged = true;
            }
            if (time != -2 && time != Time)
            {
                Time = time;
                haveChanged = true;
            }
            if (time != -2 && status != Status)
            {
                Status = status;
                haveChanged = true;

            }

            if (radioTimes != null)
            {
                foreach (var kvp in radioTimes)
                {
                    if (!RadioTimes.ContainsKey(kvp.Key))
                    {
                        RadioTimes.Add(kvp.Key, kvp.Value);
                        haveChanged = true;
                    }
                    else if (RadioTimes[kvp.Key] != kvp.Value)
                    {
                        RadioTimes[kvp.Key] = kvp.Value;
                        haveChanged = true;
                    }
                }

                List<int> toDelete = new List<int>();
                foreach (var kvp in RadioTimes)
                {
                    if (!radioTimes.ContainsKey(kvp.Key))
                    {
                        toDelete.Add(kvp.Key);
                        haveChanged = true;
                    }
                }
                foreach (int i in toDelete)
                {
                    RadioTimes.Remove(i);
                }
            }

            return haveChanged;
        }

        /// <summary>
        /// Check if otherRunner differs regarding definition or results
        /// </summary>
        /// <param name="otherRunner"></param>
        /// <returns></returns>
        public bool DefinitionEquals(Runner otherRunner)
        {
            if (ID != otherRunner.ID || FirstName != otherRunner.FirstName || LastName != otherRunner.LastName
                || ClassName != otherRunner.ClassName || ClubName != otherRunner.ClubName
                || StartTime != otherRunner.StartTime || Time != otherRunner.Time
                || Status != otherRunner.Status)
            {
                return false;
            }

            /*Check radio passings*/

            if (otherRunner.RadioTimes.Count != RadioTimes.Count)
                return false;

            Dictionary<int, int> processedControls = new Dictionary<int, int>();
            foreach (KeyValuePair<int, int> kvp in otherRunner.RadioTimes)
            {
                processedControls.Add(kvp.Key, 0);
                if (!RadioTimes.ContainsKey(kvp.Key))
                {
                    return false;
                }
                else
                {
                    if (RadioTimes[kvp.Key] != kvp.Value)
                        return false;
                }
            }

            foreach (int id in RadioTimes.Keys)
            {
                if (!processedControls.ContainsKey(id))
                    return false;
            }


            return true;
        }
    }
}
